package com.shinbada.modules.competitor.service;

import com.shinbada.excel.ExcelKit;
import com.shinbada.excel.handler.DefaultExcelReadStrategyHandlerV3;
import com.shinbada.excel.modle.CheckResult;
import com.shinbada.excel.modle.ImportExcelResult;
import com.shinbada.excel.modle.StrategyCheckService;
import com.shinbada.excel.modle.UploadModle;

import java.util.List;
import java.util.ArrayList;
import com.google.common.collect.Maps;
import java.util.Map;

import com.shinbada.modules.competitor.entity.DTO.CompetitorControlDTO;
import com.shinbada.modules.competitor.entity.VO.CompetitorControlResultVO;
import lombok.SneakyThrows;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.shinbada.core.persistence.Page;
import com.shinbada.core.service.CrudService;
import com.shinbada.modules.competitor.entity.CompetitorControl;
import com.shinbada.modules.competitor.mapper.CompetitorControlMapper;
import org.springframework.web.multipart.MultipartFile;

/**
 * 控制器Service
 * @author initcap
 * @version 2021-08-05
 */
@Service
@Transactional(readOnly = true)
public class CompetitorControlService extends CrudService<CompetitorControlMapper, CompetitorControl> implements StrategyCheckService<CompetitorControl> {

    private Map<String, String> keys;

    @Override
	public CompetitorControl get(String id) {
		return super.get(id);
	}

	@Override
	public List<CompetitorControl> findList(CompetitorControl competitorControl) {
		return super.findList(competitorControl);
	}

	@Override
	public Page<CompetitorControl> findPage(Page<CompetitorControl> page, CompetitorControl competitorControl) {
		return super.findPage(page, competitorControl);
	}

	@Transactional(readOnly = false)
	@Override
	public void save(CompetitorControl competitorControl) {
		super.save(competitorControl);
	}

	@Transactional(readOnly = false)
	@Override
	public void delete(CompetitorControl competitorControl) {
		super.delete(competitorControl);
	}

	@Transactional(readOnly = false)
	@SneakyThrows
    public ImportExcelResult<CompetitorControl> uploadExcel(MultipartFile file, UploadModle modle) {
		// 1. 准备提前数据
		readExcelInit();
		// 2. 添加数据处理器
		DefaultExcelReadStrategyHandlerV3<CompetitorControl> excelReadHandler = new DefaultExcelReadStrategyHandlerV3<>(modle, this);
		// 3. 执行导入
		ExcelKit.$Import(CompetitorControl.class).readXlsx(file.getInputStream(), excelReadHandler);
		// 4. 获得导入结果集
		ImportExcelResult<CompetitorControl> importExcelResult = excelReadHandler.results();
		// 5. 批量添加成功数据
		importExcelResult.getSuccessList().forEach(this::save);
		// 返回结果,成功的数据不返回了，影响响应速度
		importExcelResult.setSuccessList(null);
		return importExcelResult;

    }

    /**
     * @param entity 实体类
     * @return 这个key的获取决定了，在Excel导入的时候需要校验的唯一标准
     */
    private String getReadExcelKey(CompetitorControl entity) {
        return entity.getId() + entity.getRemarks();
    }

	private void readExcelInit() {
    	// 获取到现在数据库中的所有数据
    	List<CompetitorControl> db = mapper.findAllList(new CompetitorControl());
    	this.keys = Maps.newHashMapWithExpectedSize(db.size());
		// 转换键配置,请根据必要条件实现，直接使用会有问题
        db.forEach(entity -> this.keys.put(getReadExcelKey(entity), entity.getId()));
	}

	@Override
	public CheckResult readAndCheck(CompetitorControl entity) {
    	// 验证重复数据,请根据必要条件实现，直接使用会有问题
    	String key = getReadExcelKey(entity);
		if (this.keys.containsKey(key)) {
			entity.setId(this.keys.get(key));
			return CheckResult.cover(key);
		}
		// 添加数据
		this.keys.put(key, "");
		return CheckResult.pass(key);
	}

	public List<CompetitorControlResultVO> getControlTreeStructure(CompetitorControlDTO competitorControlDTO) {

		return mapper.getControlTreeStructure(competitorControlDTO);
	}

	public List<CompetitorControl> getControlByNoumenonId(String noumenonId) {
		return mapper.getControlByNoumenonId(noumenonId);
	}

	public List<CompetitorControl> getControlByNoumenonModel(String model) {

		return mapper.getControlByNoumenonModel(model);
	}
}
